// Hazel/src/Hazel/Core/Core.h
#pragma once

// 平台检测
#ifdef _WIN32
#define HZ_PLATFORM_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define HZ_PLATFORM_APPLE
#error "Apple platforms are not supported!"
#elif defined(__linux__)
#define HZ_PLATFORM_LINUX
#error "Linux is not supported yet!"
#else
#error "Unknown platform!"
#endif

// DLL 导入导出
#ifdef HZ_PLATFORM_WINDOWS
#ifdef HZ_BUILD_DLL
#define HAZEL_API __declspec(dllexport)
#else
#define HAZEL_API __declspec(dllimport)
#endif
#else
#error Hazel only supports Windows!
#endif

// 位操作宏
#define HZ_BIT(x) (1 << x)

// 启用断言（在Debug模式下）
#ifdef HZ_DEBUG
#define HZ_ENABLE_ASSERTS
#endif

// 断言宏
#ifdef HZ_ENABLE_ASSERTS
#define HZ_ASSERT(x, ...)                                   \
    {                                                       \
        if (!(x))                                           \
        {                                                   \
            HZ_ERROR("Assertion Failed: {0}", __VA_ARGS__); \
            __debugbreak();                                 \
        }                                                   \
    }
#define HZ_CORE_ASSERT(x, ...)                                   \
    {                                                            \
        if (!(x))                                                \
        {                                                        \
            HZ_CORE_ERROR("Assertion Failed: {0}", __VA_ARGS__); \
            __debugbreak();                                      \
        }                                                        \
    }
#else
#define HZ_ASSERT(x, ...)
#define HZ_CORE_ASSERT(x, ...)
#endif

// 首先包含必要的标准库头文件
#include <memory>

// 平台检测
#ifdef _WIN32
#define HZ_PLATFORM_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define HZ_PLATFORM_APPLE
#error "Apple platforms are not supported!"
#elif defined(__linux__)
#define HZ_PLATFORM_LINUX
#error "Linux is not supported yet!"
#else
#error "Unknown platform!"
#endif

// DLL 导入导出
#ifdef HZ_PLATFORM_WINDOWS
#ifdef HZ_BUILD_DLL
#define HAZEL_API __declspec(dllexport)
#else
#define HAZEL_API __declspec(dllimport)
#endif
#else
#error Hazel only supports Windows!
#endif

// 位操作宏
#define HZ_BIT(x) (1 << x)

// 启用断言
#ifdef HZ_DEBUG
#define HZ_ENABLE_ASSERTS
#endif

#ifdef HZ_ENABLE_ASSERTS
#define HZ_ASSERT(x, ...)                                   \
    {                                                       \
        if (!(x))                                           \
        {                                                   \
            HZ_ERROR("Assertion Failed: {0}", __VA_ARGS__); \
            __debugbreak();                                 \
        }                                                   \
    }
#define HZ_CORE_ASSERT(x, ...)                                   \
    {                                                            \
        if (!(x))                                                \
        {                                                        \
            HZ_CORE_ERROR("Assertion Failed: {0}", __VA_ARGS__); \
            __debugbreak();                                      \
        }                                                        \
    }
#else
#define HZ_ASSERT(x, ...)
#define HZ_CORE_ASSERT(x, ...)
#endif

// 函数绑定宏
#define HZ_BIND_EVENT_FN(fn) [this](auto &&...args) -> decltype(auto) { return this->fn(std::forward<decltype(args)>(args)...); }

// ============================================================================
// TheCherno 风格的智能指针别名
// ============================================================================

namespace Hazel
{

    // 智能指针别名定义在 Hazel 命名空间内
    template <typename T>
    using Scope = std::unique_ptr<T>;

    template <typename T, typename... Args>
    constexpr Scope<T> CreateScope(Args &&...args)
    {
        return std::make_unique<T>(std::forward<Args>(args)...);
    }

    template <typename T>
    using Ref = std::shared_ptr<T>;

    template <typename T, typename... Args>
    constexpr Ref<T> CreateRef(Args &&...args)
    {
        return std::make_shared<T>(std::forward<Args>(args)...);
    }

} // namespace Hazel

// 函数绑定宏
#define HZ_BIND_EVENT_FN(fn) [this](auto &&...args) -> decltype(auto) { return this->fn(std::forward<decltype(args)>(args)...); }

// 键盘按键编码（简化版）
#define HZ_KEY_SPACE 32
#define HZ_KEY_APOSTROPHE 39 /* ' */
#define HZ_KEY_COMMA 44      /* , */
#define HZ_KEY_MINUS 45      /* - */
#define HZ_KEY_PERIOD 46     /* . */
#define HZ_KEY_SLASH 47      /* / */
#define HZ_KEY_0 48
#define HZ_KEY_1 49
#define HZ_KEY_2 50
#define HZ_KEY_3 51
#define HZ_KEY_4 52
#define HZ_KEY_5 53
#define HZ_KEY_6 54
#define HZ_KEY_7 55
#define HZ_KEY_8 56
#define HZ_KEY_9 57
#define HZ_KEY_SEMICOLON 59 /* ; */
#define HZ_KEY_EQUAL 61     /* = */
#define HZ_KEY_A 65
#define HZ_KEY_B 66
#define HZ_KEY_C 67
#define HZ_KEY_D 68
#define HZ_KEY_E 69
#define HZ_KEY_F 70
#define HZ_KEY_G 71
#define HZ_KEY_H 72
#define HZ_KEY_I 73
#define HZ_KEY_J 74
#define HZ_KEY_K 75
#define HZ_KEY_L 76
#define HZ_KEY_M 77
#define HZ_KEY_N 78
#define HZ_KEY_O 79
#define HZ_KEY_P 80
#define HZ_KEY_Q 81
#define HZ_KEY_R 82
#define HZ_KEY_S 83
#define HZ_KEY_T 84
#define HZ_KEY_U 85
#define HZ_KEY_V 86
#define HZ_KEY_W 87
#define HZ_KEY_X 88
#define HZ_KEY_Y 89
#define HZ_KEY_Z 90
#define HZ_KEY_LEFT_BRACKET 91  /* [ */
#define HZ_KEY_BACKSLASH 92     /* \ */
#define HZ_KEY_RIGHT_BRACKET 93 /* ] */
#define HZ_KEY_GRAVE_ACCENT 96  /* ` */
#define HZ_KEY_ESCAPE 256
